package com.kdgc.power.common.util;


import com.nlf.calendar.Lunar;
import com.nlf.calendar.LunarMonth;
import com.nlf.calendar.Solar;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.Year;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.Calendar;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class LocalDateUtil {
    public static void getDay(Object day, long daysToAdd) {
        getDay(toLocalDate(day).plusDays(daysToAdd));
    }

    public static void getDay(int day) {
        getDay(LocalDate.now(), day);
    }

    public static void getDay() {
        getDay(LocalDate.now());
    }

    public static void getDay(long time) {
        getDay(toLocalDate(time));
    }

    public static void getDay(int year, int month, int day) {
        getDay(LocalDate.of(year, month, day));
    }

    public static void getDay(String day, String pattern) {
        getDay(LocalDate.parse(day, DateTimeFormatter.ofPattern(pattern)));
    }

    public static void getDay(Object day) {
        LocalDate localDate = toLocalDate(day);
        LocalDate nowDay = LocalDate.now();
        long diff = nowDay.until(localDate, ChronoUnit.DAYS);
        String diffDetail;
        if (diff < 0) {
            diffDetail = -diff + "天前";
        } else if (diff == 0) {
            diffDetail = "今天";
        } else {
            diffDetail = diff + "天后";
        }
        Lunar lunar = new Lunar(new Solar(localDate.getYear(), localDate.getMonthValue(), localDate.getDayOfMonth()));
        String termName = lunar.getJieQi();
        String s = localDate +
                " 星期" +
                lunar.getWeekInChinese() +
                " " +
                lunar.getYearInGanZhi() +
                "年 农历" +
                lunar.getMonthInChinese() +
                "月" +
                lunar.getDayInChinese() +
                (StringUtil.isEmpty(termName) ? " " : "(" + termName + ") ") +
                diffDetail;
        System.out.println(s);

    }


    public static void getDay(int lunarYear, int lunarMonth, int dayOfLunarMonth, boolean isLeap) {
        if (!isLeap) {
            getDay(Lunar.fromYmd(lunarYear, lunarMonth, dayOfLunarMonth));
        } else {
            LunarMonth month = LunarMonth.fromYm(lunarYear, lunarMonth);
            LunarMonth next = month.next(1);
            if (next.isLeap()) {
                if (dayOfLunarMonth > next.getDayCount()) {
                    throw new IllegalArgumentException(String.format("only %d days in lunar year %d month %d+", next.getDayCount(), lunarYear, lunarMonth));
                }
                getDay(Lunar.fromYmd(lunarYear, lunarMonth, dayOfLunarMonth), month.getDayCount());
            } else {
                getDay(Lunar.fromYmd(lunarYear, lunarMonth, dayOfLunarMonth));
            }

        }
    }

    public static long getDayDiff(Object day1, Object day2) {
        return toLocalDate(day1).until(toLocalDate(day2), ChronoUnit.DAYS);
    }


    public static void getSolarYear() {
        getDay(Year.now().getValue() + 1, 1, 1);
    }

    public static void getSolarYear(int year) {
        getDay(LocalDate.of(year, 1, 1));
    }


    public static void getLunarYear() {
        getDay(Lunar.fromYmd(new Lunar().getYear() + 1, 1, 1));
    }

    public static void getLunarYear(int year) {
        getDay(Lunar.fromYmd(year, 1, 1));
    }

    public static LocalDate toLocalDate(Object day) {
        if (day instanceof LocalDate) {
            return (LocalDate) day;
        } else if (day instanceof Calendar) {
            Calendar calendar = (Calendar) day;
            return LocalDate.of(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH) + 1, calendar.get(Calendar.DATE));
        } else if (day instanceof Date) {
            Date date = (Date) day;
            return toLocalDate(date.getTime());
        } else if (day instanceof LocalDateTime) {
            LocalDateTime localDateTime = (LocalDateTime) day;
            return localDateTime.toLocalDate();
        } else if (day instanceof Lunar) {
            Lunar lunar = (Lunar) day;
            return toLocalDate(lunar.getSolar());
        } else {
            String dayStr = StringUtil.toString(day);
            Matcher matcher = Pattern.compile("\\d+").matcher(dayStr);
            int count = 1;
            String year = null;
            String month = null;
            String dayOfMonth = null;
            while (matcher.find()) {
                if (count == 1) {
                    year = matcher.group();
                } else if (count == 2) {
                    month = matcher.group();
                } else if (count == 3) {
                    dayOfMonth = matcher.group();
                    break;
                }
                count++;
            }
            if (dayOfMonth != null) {
                assert month != null;
                return LocalDate.of(Integer.parseInt(year), Integer.parseInt(month), Integer.parseInt(dayOfMonth));
            } else {
                throw new IllegalArgumentException(day + "可能不是日期");
            }
        }
    }

    public static LocalDate toLocalDate(long time) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(time);
        return LocalDate.of(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH) + 1, calendar.get(Calendar.DATE));
    }

}
